﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SimpleModeler.Graphics;
using OpenTK;
using SimpleModeler.Textures;

namespace SimpleModeler.GUI
{
    /// <summary>
    /// EditObjectWindow
    /// </summary>
    public partial class EditObjectWindow : Form
    {
        #region Fields
        private SceneObject _obj;
        private SceneObject _orgiginal;
        private ColorDialog _colorDialog;
        #endregion // Fields


        #region Properties
        /// <summary>
        /// Aktuelles SceneObject
        /// </summary>
        public SceneObject Obj 
        { 
            get{return _obj;}
            set 
            { 
                if(value != null)
                    this._orgiginal = (SceneObject)value.Clone();
                this._obj = value; SetObj(); 
            }
        }
        #endregion // Properties


        #region Constructors
        /// <summary>
        /// Konstruktor
        /// </summary>
        public EditObjectWindow() : this(null) { }
        /// <summary>
        /// Konstruktor
        /// </summary>
        /// <param name="obj">Selektiertes Objekt</param>
        public EditObjectWindow(SceneObject obj)
        {
            InitializeComponent();
            _colorDialog = new ColorDialog();            

            this.Obj = obj;

            this.numPosX.ValueChanged += new System.EventHandler(this.pos_ValueChanged);
            this.numPosY.ValueChanged += new System.EventHandler(this.pos_ValueChanged);
            this.numPosZ.ValueChanged += new System.EventHandler(this.pos_ValueChanged);

            this.numRotX.ValueChanged += new EventHandler(this.numRot_ValueChanged);
            this.numRotY.ValueChanged += new EventHandler(this.numRot_ValueChanged);
            this.numRotZ.ValueChanged += new EventHandler(this.numRot_ValueChanged);
        }
        #endregion // Constructors


        #region Methods
        #region EventHandlers
        private void butChangeColor_Click(object sender, EventArgs e)
        {
            if (_colorDialog.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
                SetColor(_colorDialog.Color);
        }

        private void butChangePosition_Click(object sender, EventArgs e)
        {
            float x;
            float y;
            float z;

            x = Convert.ToSingle(this.numPosX.Value);
            y = Convert.ToSingle(this.numPosY.Value);
            z = Convert.ToSingle(this.numPosZ.Value);

            SetPosition(new Vector3(x, y, z));
        }

        private void pos_ValueChanged(object sender, EventArgs e)
        {
            float x = 0, y = 0, z = 0;

            if (sender == this.numPosX)
                x = Convert.ToSingle(numPosX.Value) - this._obj.Coordinate.X;
            else if (sender == this.numPosY)
                y = Convert.ToSingle(numPosY.Value) - this._obj.Coordinate.Y;
            else if (sender == this.numPosZ)
                z = Convert.ToSingle(numPosZ.Value) - this._obj.Coordinate.Z;
            if (x != 0 || y != 0 || z != 0)
                SetPosition(this._obj.Coordinate + new Vector3(x, y, z));
        }

        void numRot_ValueChanged(object sender, EventArgs e)
        {
            float x = 0, y = 0, z = 0;

            if (sender == this.numRotX)
                x = Convert.ToSingle(numRotX.Value) - this._obj.Rotation.X;
            else if (sender == this.numRotY)
                y = Convert.ToSingle(numRotY.Value) - this._obj.Rotation.Y;
            else if (sender == this.numRotZ)
                z = Convert.ToSingle(numRotZ.Value) - this._obj.Rotation.Z;
            if (x != 0 || y != 0 || z != 0)
                SetRotation(this._obj.Rotation + new Vector3(x, y, z));
        }
        
        private void numGroesse_ValueChanged(object sender, EventArgs e)
        {
            float groesse = 0;
            groesse = Convert.ToSingle(numGroesse.Value);
            if (groesse != 0)
                SetSize(new Vector3(groesse, groesse, groesse));
        }

        private void butTexture_Click(object sender, EventArgs e)
        {
            OpenFileDialog fd = new OpenFileDialog();
            fd.Filter = "Bilddateien (*.jpg; *.jpe; *.jpeg; *.png; *.gif; *.bmp; *.tif; *.tga)|*.jpg; *.jpe; *jpeg; *.png; *.gif; *.bmp; *.tif; *.tga|Alle Dateien (*.*)|*.*";
            fd.InitialDirectory = String.Format(@"{0}\data\textures", Environment.CurrentDirectory);
            if (fd.ShowDialog() == DialogResult.OK)
            {
                string filename = fd.FileName;
                Texture2D texture = new Texture2D(filename);
                SetTexture(texture);
            }
        }
        #endregion // EventHandlers

        /// <summary>
        /// Setzt das Objekt
        /// </summary>
        private void SetObj()
        {
            if (this._obj == null)
                this.Enabled = false;
            else
            {
                this.Enabled = true;
                SetColor(this._obj.Color);
                SetPosition(this._obj.Coordinate);
                SetRotation(this._obj.Rotation);
                SetSize(this._obj.Size);
                SetTexture((Texture2D)this._obj.Texture);
            }
        }

        /// <summary>
        /// Setzt die Farbe im aktuellen Kontext
        /// </summary>
        /// <param name="c">Farbe</param>
        private void SetColor(Color c)
        {
            this._obj.Color = c;
            _colorDialog.Color = c;
            this.pnlColor.BackColor = c;
        }

        /// <summary>
        /// Setzt die Position im aktuellen Kontext
        /// </summary>
        /// <param name="position">Positionsvekotr</param>
        private void SetPosition(Vector3 position)
        {
            this._obj.Coordinate = position;
            this.numPosX.Value = Convert.ToDecimal(position.X);
            this.numPosY.Value = Convert.ToDecimal(position.Y);
            this.numPosZ.Value = Convert.ToDecimal(position.Z);
        }

        /// <summary>
        /// Setzt die Rotation im aktuellen Kontext
        /// </summary>
        /// <param name="rotation">Rotationsvektor</param>
        private void SetRotation(Vector3 rotation)
        {
            this._obj.Rotation = rotation;
            this.numRotX.Value = Convert.ToDecimal(rotation.X);
            this.numRotY.Value = Convert.ToDecimal(rotation.Y);
            this.numRotZ.Value = Convert.ToDecimal(rotation.Z);
        }

        /// <summary>
        /// Setzt die Größe im aktuellen Kontext
        /// </summary>
        /// <param name="size">Größenvektor</param>
        private void SetSize(Vector3 size)
        {
            this._obj.Size = size;
            this.numGroesse.Value = Convert.ToDecimal(size.X);
        }

        /// <summary>
        /// Setzt die Textur im aktuellen Kontext
        /// </summary>
        /// <param name="texture">Textur</param>
        private void SetTexture(Texture2D texture)
        {
            if (this._obj != null)
            {
                this.textBoxTexture.Text = this._obj.Texture != null ? texture.File : "";
                this._obj.Texture = texture;
            }
        }

        #endregion // Methods
    }
}
